home *** CD-ROM | disk | FTP | other *** search
- package com.extensibility.rock;
-
- import java.awt.Image;
- import java.awt.image.ImageProducer;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.util.Hashtable;
-
- public class GifEncoder extends ImageEncoder {
- private boolean interlace = false;
- int width;
- int height;
- byte[][] rgbPixels;
- private final int HASH_PRIME;
- private int colorsUsed = 0;
- GifEncoderHashitem[] hashArray = new GifEncoderHashitem[509];
- Hashtable colorHash;
- int Width;
- int Height;
- boolean Interlace;
- int curx;
- int cury;
- int CountDown;
- int Pass = 0;
- static final int EOF = -1;
- static final int BITS = 12;
- static final int HSIZE = 5003;
- int n_bits;
- int maxbits = 12;
- int maxcode;
- int maxmaxcode = 4096;
- int[] htab = new int[5003];
- int[] codetab = new int[5003];
- int hsize = 5003;
- int free_ent = 0;
- boolean clear_flg = false;
- int g_init_bits;
- int ClearCode;
- int EOFCode;
- int cur_accum = 0;
- int cur_bits = 0;
- int[] masks = new int[]{0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535};
- int a_count;
- byte[] accum = new byte[256];
-
- public GifEncoder(Image var1, OutputStream var2) throws IOException {
- super(var1, var2);
- super.allowAccumulate = false;
- }
-
- public GifEncoder(Image var1, OutputStream var2, boolean var3) throws IOException {
- super(var1, var2);
- this.interlace = var3;
- super.allowAccumulate = false;
- }
-
- public GifEncoder(ImageProducer var1, OutputStream var2) throws IOException {
- super(var1, var2);
- super.allowAccumulate = false;
- }
-
- public GifEncoder(ImageProducer var1, OutputStream var2, boolean var3) throws IOException {
- super(var1, var2);
- this.interlace = var3;
- super.allowAccumulate = false;
- }
-
- void encodeStart(int var1, int var2) throws IOException {
- this.width = var1;
- this.height = var2;
- this.rgbPixels = new byte[var2][var1];
- }
-
- private byte hashColor(int var1) {
- int var2 = (var1 & 16777215) % 509;
- GifEncoderHashitem var3 = this.hashArray[var2];
- if (var3 == null || var3.rgb != var1) {
- for(; var3 != null && var3.rgb != var1; var3 = this.hashArray[var2]) {
- ++var2;
- if (var2 == 509) {
- var2 = 0;
- }
- }
-
- if (var3 == null) {
- var3 = new GifEncoderHashitem(var1, 0, this.colorsUsed++, false);
- this.hashArray[var2] = var3;
- }
- }
-
- ++var3.count;
- return (byte)var3.index;
- }
-
- void encodePixels(int var1, int var2, int var3, int var4, int[] var5, int var6, int var7) {
- for(int var8 = 0; var8 < var4; ++var8) {
- for(int var9 = 0; var9 < var3; ++var9) {
- this.rgbPixels[var2 + var8][var1 + var9] = this.hashColor(var5[var8 * var7 + var6 + var9]);
- }
- }
-
- }
-
- void encodeDone() throws IOException {
- if (this.colorsUsed >= 256) {
- throw new IOException("too many colors for a GIF");
- } else {
- byte var1;
- if (this.colorsUsed <= 2) {
- var1 = 1;
- } else if (this.colorsUsed <= 4) {
- var1 = 2;
- } else if (this.colorsUsed <= 16) {
- var1 = 4;
- } else {
- var1 = 8;
- }
-
- int var2 = 1 << var1;
- byte[] var3 = new byte[var2];
- byte[] var4 = new byte[var2];
- byte[] var5 = new byte[var2];
-
- for(int var6 = 0; var6 < 509; ++var6) {
- GifEncoderHashitem var7 = this.hashArray[var6];
- if (var7 != null) {
- var3[var7.index] = (byte)(var7.rgb >> 16 & 255);
- var4[var7.index] = (byte)(var7.rgb >> 8 & 255);
- var5[var7.index] = (byte)(var7.rgb & 255);
- }
- }
-
- this.GIFEncode(super.out, this.width, this.height, this.interlace, (byte)0, -1, var1, var3, var4, var5);
- }
- }
-
- byte GetPixel(int var1, int var2) {
- return this.rgbPixels[var2][var1];
- }
-
- static void writeString(OutputStream var0, String var1) throws IOException {
- byte[] var2 = var1.getBytes();
- var0.write(var2);
- }
-
- void GIFEncode(OutputStream var1, int var2, int var3, boolean var4, byte var5, int var6, int var7, byte[] var8, byte[] var9, byte[] var10) throws IOException {
- this.Width = var2;
- this.Height = var3;
- this.Interlace = var4;
- int var14 = 1 << var7;
- byte var13 = 0;
- byte var12 = 0;
- this.CountDown = var2 * var3;
- this.Pass = 0;
- int var15;
- if (var7 <= 1) {
- var15 = 2;
- } else {
- var15 = var7;
- }
-
- this.curx = 0;
- this.cury = 0;
- writeString(var1, "GIF89a");
- this.Putword(var2, var1);
- this.Putword(var3, var1);
- byte var11 = -128;
- var11 = (byte)(var11 | 112);
- var11 = (byte)(var11 | (byte)(var7 - 1));
- this.Putbyte(var11, var1);
- this.Putbyte(var5, var1);
- this.Putbyte((byte)0, var1);
-
- for(int var16 = 0; var16 < var14; ++var16) {
- this.Putbyte(var8[var16], var1);
- this.Putbyte(var9[var16], var1);
- this.Putbyte(var10[var16], var1);
- }
-
- if (var6 != -1) {
- this.Putbyte((byte)33, var1);
- this.Putbyte((byte)-7, var1);
- this.Putbyte((byte)4, var1);
- this.Putbyte((byte)1, var1);
- this.Putbyte((byte)0, var1);
- this.Putbyte((byte)0, var1);
- this.Putbyte((byte)var6, var1);
- this.Putbyte((byte)0, var1);
- }
-
- this.Putbyte((byte)44, var1);
- this.Putword(var12, var1);
- this.Putword(var13, var1);
- this.Putword(var2, var1);
- this.Putword(var3, var1);
- if (var4) {
- this.Putbyte((byte)64, var1);
- } else {
- this.Putbyte((byte)0, var1);
- }
-
- this.Putbyte((byte)var15, var1);
- this.compress(var15 + 1, var1);
- this.Putbyte((byte)0, var1);
- this.Putbyte((byte)59, var1);
- }
-
- void BumpPixel() {
- ++this.curx;
- if (this.curx == this.Width) {
- this.curx = 0;
- if (!this.Interlace) {
- ++this.cury;
- } else {
- switch (this.Pass) {
- case 0:
- this.cury += 8;
- if (this.cury >= this.Height) {
- ++this.Pass;
- this.cury = 4;
- }
- break;
- case 1:
- this.cury += 8;
- if (this.cury >= this.Height) {
- ++this.Pass;
- this.cury = 2;
- }
- break;
- case 2:
- this.cury += 4;
- if (this.cury >= this.Height) {
- ++this.Pass;
- this.cury = 1;
- }
- break;
- case 3:
- this.cury += 2;
- }
- }
- }
-
- }
-
- int GIFNextPixel() throws IOException {
- if (this.CountDown == 0) {
- return -1;
- } else {
- --this.CountDown;
- byte var1 = this.GetPixel(this.curx, this.cury);
- this.BumpPixel();
- return var1 & 255;
- }
- }
-
- void Putword(int var1, OutputStream var2) throws IOException {
- this.Putbyte((byte)(var1 & 255), var2);
- this.Putbyte((byte)(var1 >> 8 & 255), var2);
- }
-
- void Putbyte(byte var1, OutputStream var2) throws IOException {
- var2.write(var1);
- }
-
- final int MAXCODE(int var1) {
- return (1 << var1) - 1;
- }
-
- void compress(int var1, OutputStream var2) throws IOException {
- this.g_init_bits = var1;
- this.clear_flg = false;
- this.n_bits = this.g_init_bits;
- this.maxcode = this.MAXCODE(this.n_bits);
- this.ClearCode = 1 << var1 - 1;
- this.EOFCode = this.ClearCode + 1;
- this.free_ent = this.ClearCode + 2;
- this.char_init();
- int var6 = this.GIFNextPixel();
- int var9 = 0;
-
- for(int var3 = this.hsize; var3 < 65536; var3 *= 2) {
- ++var9;
- }
-
- var9 = 8 - var9;
- int var8 = this.hsize;
- this.cl_hash(var8);
- this.output(this.ClearCode, var2);
-
- int var5;
- label43:
- while((var5 = this.GIFNextPixel()) != -1) {
- int var10 = (var5 << this.maxbits) + var6;
- int var4 = var5 << var9 ^ var6;
- if (this.htab[var4] == var10) {
- var6 = this.codetab[var4];
- } else {
- if (this.htab[var4] >= 0) {
- int var7 = var8 - var4;
- if (var4 == 0) {
- var7 = 1;
- }
-
- do {
- if ((var4 -= var7) < 0) {
- var4 += var8;
- }
-
- if (this.htab[var4] == var10) {
- var6 = this.codetab[var4];
- continue label43;
- }
- } while(this.htab[var4] >= 0);
- }
-
- this.output(var6, var2);
- var6 = var5;
- if (this.free_ent < this.maxmaxcode) {
- this.codetab[var4] = this.free_ent++;
- this.htab[var4] = var10;
- } else {
- this.cl_block(var2);
- }
- }
- }
-
- this.output(var6, var2);
- this.output(this.EOFCode, var2);
- }
-
- void output(int var1, OutputStream var2) throws IOException {
- this.cur_accum &= this.masks[this.cur_bits];
- if (this.cur_bits > 0) {
- this.cur_accum |= var1 << this.cur_bits;
- } else {
- this.cur_accum = var1;
- }
-
- for(this.cur_bits += this.n_bits; this.cur_bits >= 8; this.cur_bits -= 8) {
- this.char_out((byte)(this.cur_accum & 255), var2);
- this.cur_accum >>= 8;
- }
-
- if (this.free_ent > this.maxcode || this.clear_flg) {
- if (this.clear_flg) {
- this.maxcode = this.MAXCODE(this.n_bits = this.g_init_bits);
- this.clear_flg = false;
- } else {
- ++this.n_bits;
- if (this.n_bits == this.maxbits) {
- this.maxcode = this.maxmaxcode;
- } else {
- this.maxcode = this.MAXCODE(this.n_bits);
- }
- }
- }
-
- if (var1 == this.EOFCode) {
- while(this.cur_bits > 0) {
- this.char_out((byte)(this.cur_accum & 255), var2);
- this.cur_accum >>= 8;
- this.cur_bits -= 8;
- }
-
- this.flush_char(var2);
- }
-
- }
-
- void cl_block(OutputStream var1) throws IOException {
- this.cl_hash(this.hsize);
- this.free_ent = this.ClearCode + 2;
- this.clear_flg = true;
- this.output(this.ClearCode, var1);
- }
-
- void cl_hash(int var1) {
- for(int var2 = 0; var2 < var1; ++var2) {
- this.htab[var2] = -1;
- }
-
- }
-
- void char_init() {
- this.a_count = 0;
- }
-
- void char_out(byte var1, OutputStream var2) throws IOException {
- this.accum[this.a_count++] = var1;
- if (this.a_count >= 254) {
- this.flush_char(var2);
- }
-
- }
-
- void flush_char(OutputStream var1) throws IOException {
- if (this.a_count > 0) {
- var1.write(this.a_count);
- var1.write(this.accum, 0, this.a_count);
- this.a_count = 0;
- }
-
- }
- }
-